home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 October: Mac OS SDK / Dev.CD Oct 00 SDK1.toast / Development Kits / Mac OS / MLTE SDK / TEtoMLTESample / MLTESources / MLTEDocument.cp next >
Encoding:
Text File  |  2000-03-02  |  18.2 KB  |  555 lines  |  [TEXT/MPS ]

  1. /*------------------------------------------------------------------------------
  2. #
  3. #    Apple Macintosh Developer Technical Support
  4. #
  5. #    MultiFinder-Aware Simple TextEdit Sample Application
  6. #
  7. #    CPlusTESample
  8. #
  9. #    TEDocument.cp    -    C++ source
  10. #
  11. #    Copyright © 1989 Apple Computer, Inc.
  12. #    All rights reserved.
  13. #
  14. #    Versions:    
  15. #            1.10                     07/89
  16. #            1.00                     04/89
  17. #
  18. #    Components:
  19. #            CPlusTESample.make        July 9, 1989
  20. #            TApplicationCommon.h    July 9, 1989
  21. #            TApplication.h            July 9, 1989
  22. #            TDocument.h                July 9, 1989
  23. #            TECommon.h                July 9, 1989
  24. #            TESample.h                July 9, 1989
  25. #            TEDocument.h            July 9, 1989
  26. #            TApplication.cp            July 9, 1989
  27. #            TDocument.cp            July 9, 1989
  28. #            TESample.cp                July 9, 1989
  29. #            TEDocument.cp            July 9, 1989
  30. #            TESampleGlue.a            July 9, 1989
  31. #            TApplication.r            July 9, 1989
  32. #            TESample.r                July 9, 1989
  33. #
  34. #    CPlusTESample is an example application that demonstrates
  35. #    how to initialize the commonly used toolbox managers,
  36. #    operate successfully under MultiFinder, handle desk
  37. #    accessories and create, grow, and zoom windows. The
  38. #    fundamental TextEdit toolbox calls and TextEdit autoscroll
  39. #    are demonstrated. It also shows how to create and maintain
  40. #    scrollbar controls. 
  41. #
  42. #    This version of TESample has been substantially reworked in
  43. #    C++ to show how a "typical" object oriented program could
  44. #    be written. To this end, what was once a single source code
  45. #    file has been restructured into a set of classes which
  46. #    demonstrate the advantages of object-oriented programming.
  47. #
  48. ------------------------------------------------------------------------------*/
  49.  
  50.  
  51. /*
  52. Segmentation strategy:
  53.  
  54.     This program has only one segment, since the issues
  55.     surrounding segmentation within a class's methods have
  56.     not been investigated yet. We DO unload the data
  57.     initialization segment at startup time, which frees up
  58.     some memory 
  59.  
  60. SetPort strategy:
  61.  
  62.     Toolbox routines do not change the current port. In
  63.     spite of this, in this program we use a strategy of
  64.     calling SetPort whenever we want to draw or make calls
  65.     which depend on the current port. This makes us less
  66.     vulnerable to bugs in other software which might alter
  67.     the current port (such as the bug (feature?) in many
  68.     desk accessories which change the port on OpenDeskAcc).
  69.     Hopefully, this also makes the routines from this
  70.     program more self-contained, since they don't depend on
  71.     the current port setting. 
  72.  
  73. Clipboard strategy:
  74.  
  75.     This program does not maintain a private scrap.
  76.     Whenever a cut, copy, or paste occurs, we import/export
  77.     from the public scrap to TextEdit's scrap right away,
  78.     using the TEToScrap and TEFromScrap routines. If we did
  79.     use a private scrap, the import/export would be in the
  80.     activate/deactivate event and suspend/resume event
  81.     routines. 
  82. */
  83.  
  84. // Mac Includes
  85. #include <Types.h>
  86. #include <Quickdraw.h>
  87. #include <Fonts.h>
  88. #include <Controls.h>
  89. #include <Windows.h>
  90. #include <TextEdit.h>
  91. #include <Dialogs.h>
  92. #include <Menus.h>
  93. #include <Devices.h>
  94. #include <Events.h> 
  95. #include <Scrap.h>
  96. #include <ToolUtils.h>
  97. #include <Memory.h>
  98. #include <SegLoad.h>
  99. #include <Files.h>
  100. #include <OSUtils.h>
  101. #include <Traps.h>
  102. #include <LowMem.h>
  103. #include <Controls.h>
  104. #include <TextUtils.h>
  105. #include <MacTextEditor.h>
  106.  
  107. #include "MLTEDocument.h" 
  108. // we need resource definitions
  109. #include "TECommon.h"
  110.  
  111. // #include "TESample.h"
  112.  
  113. //change 1 remove the  control functions
  114.  
  115. // kTextMargin is the number of pixels we leave blank at the edge of the window.
  116.     const short kTextMargin = 2;
  117.  
  118. // kMaxDocWidth is an arbitrary number used to specify the width of the TERec's
  119. // destination rectangle so that word wrap and horizontal scrolling can be
  120. // demonstrated.
  121.     const short    kMaxDocWidth = 576;
  122.     
  123. // kMinDocDim is used to limit the minimum dimension of a window when GrowWindow
  124. // is called.
  125. //change: remove kMinDocDim
  126.     
  127. // kMaxTELength is an arbitrary number used to limit the length of text in the TERec
  128. // so that various errors won't occur from too many characters being in the text.
  129. // change: remove kMaxTELength
  130.  
  131. // kControlInvisible is used the same way to 'turn on' the control.
  132. // change 2 remove kControlVisible
  133.  
  134. // ScrollBarAdjust, GrowBoxAdjust, and ScrollBar width are used in calculating
  135. // values for control positioning and sizing.
  136. // change 3 remove the constants associated with scrolling and the Growbox
  137.  
  138. // kTESlop provides some extra security when pre-flighting edit commands.
  139. // change 4 remove the kTESlop
  140.  
  141. // kScrollTweek compensates for off-by-one requirements of the scrollbars
  142. // to have borders coincide with the growbox.
  143. // change 5 remove the kScrollTweek
  144.     
  145. // kCrChar is used to match with a carriage return when calculating the
  146. // number of lines in the TextEdit record. kDelChar is used to check for
  147. // delete in keyDowns.
  148. // change 6 remove kCrChar and kDelChar
  149.     
  150. // Use universal procedure pointers that are compatible with both 68K and PowerPC.
  151. // change 7 remove the procedure pointers 
  152.     Boolean             inited = false;
  153.     
  154.  
  155. /***********************************************************************/
  156. //
  157. // TEDocument class declarations
  158. //
  159. /***********************************************************************/
  160.  
  161. //-----------------------------------------------------------------------
  162. // TEDocument::TEDocument -    notice that we pass the resID parameter up to our
  163. //                            base class, which actually creates the window for us.
  164. //                            If you modify this so that it doesn't create a
  165. //                            window, be sure to take that into account in the
  166. //                            application class so that it doesn't believe an
  167. //                            error occurred (as version 1.20 of TApplication
  168. //                            would).
  169. //
  170. TEDocument::TEDocument( short resID )    : TDocument( resID )
  171. {
  172.         //change remove good
  173.         //change remove Rect destRect, viewRect;
  174.         OSStatus    status;        //change add an OSStatus
  175.         
  176.         // initialize routine desciptors once
  177.         if (!inited)
  178.         {
  179.             // change 8 remove the calls to NewControlActionProc
  180.             // and NewTEClickLoopProc
  181.             inited = true;
  182.         }
  183.  
  184.         SetPort( fDocWindow );
  185.         //change 8 remove the call to GetTERect which we don't need anymore
  186.         //and the rectangle manipulations
  187.  
  188.         //change 9 replace call to TENew with a call to TXNNewObject
  189.         status = TXNNewObject(    
  190.                         NULL, /* can be NULL */
  191.                          fDocWindow,
  192.                         NULL, /* can be NULL */
  193.                          kTXNShowWindowMask|kTXNWantHScrollBarMask|kTXNWantVScrollBarMask|kTXNSaveStylesAsSTYLResourceMask|kTXNDrawGrowIconMask,
  194.                          kTXNTextEditStyleFrameType, /* the only valid option */
  195.                          kTXNTextFile,
  196.                          kTXNSystemDefaultEncoding,
  197.                          &fMLTEObject,
  198.                          &fMLTEFrameID,
  199.                          NULL
  200.                      );
  201.         
  202.         //change use of fDocTE to fMLTEObject and test the function result
  203.         //also remove all the control calls and the call to TEAutoView
  204.         if ( fMLTEObject == NULL || status != noErr )    // if TENew succeeded, we have a good document 
  205.             AlertUser( kTEDocErrStrings, eNoWindow );            // tell user we failed
  206.             
  207. } /* TEDocument (constructor) */
  208.  
  209.  
  210. //-----------------------------------------------------------------------
  211. // TEDocument::~TEDocument -    At this point, if there was a document associated 
  212. //                                with a window, you could do any document saving
  213. //                                processing if it is 'dirty'. DoCloseWindow would
  214. //                                return true if the window actually closed, i.e.,
  215. //                                the user didn’t cancel from a save dialog. This
  216. //                                result is handy whenthe user quits an application,
  217. //                                but then cancels the save of a documentassociated
  218. //                                with a window.
  219. //
  220.     TEDocument::~TEDocument(void)
  221.     {
  222.         HideWindow( fDocWindow );
  223.         
  224.         // get rid of any extra storage that was used for the window
  225.         // change for this do a TXNDeleteObject
  226.             if ( fMLTEObject != nil )
  227.                 TXNDeleteObject(fMLTEObject);                                    // dispose the TEHandle if we got far enough to make one 
  228.         
  229.         //change no more reason to call DisposeControl
  230.     
  231.         // base class destructor will dispose of window
  232.     } /* TEDocument (destructor) */
  233.  
  234.  
  235. //-----------------------------------------------------------------------
  236. // TEDocument::DoZoom -     
  237. //
  238.     void TEDocument::DoZoom( short partCode )
  239.     {
  240.     //change replace the guts of this whole function with a call to TXNZoomWindow
  241.         TXNZoomWindow( fMLTEObject,partCode);
  242.         
  243.     } /* TEDocument::DoZoom */
  244.  
  245.  
  246. //-----------------------------------------------------------------------
  247. // TEDocument::DoGrow -    Called when a mouseDown occurs in the grow box of
  248. //                        an active window.
  249. //
  250.     void TEDocument::DoGrow( EventRecord* theEvent )
  251.     {
  252.         //change replace the guts of this function with a call to TXNGrowWindow
  253.         TXNGrowWindow( fMLTEObject, theEvent );
  254.     } /* TEDocument::DoGrow */
  255.  
  256.  
  257. //-----------------------------------------------------------------------
  258. // TEDocument::DoContent -    
  259. //
  260.     void TEDocument::DoContent( EventRecord* theEvent )
  261.     {
  262.         //change replace the guts with a call to TXNClick
  263.         TXNClick(fMLTEObject,theEvent);
  264.     } /* TEDocument::DoContent */
  265.  
  266.  
  267. //-----------------------------------------------------------------------
  268. // TEDocument::DoKeyDown -    
  269. //
  270.     void TEDocument::DoKeyDown( EventRecord* theEvent )
  271.     {
  272.         //replace the guts of this routine with a call to TXNKeyDown
  273.         TXNKeyDown ( fMLTEObject, theEvent );
  274.             
  275.     } /* TEDocument::DoKeyDown */
  276.  
  277.  
  278. //-----------------------------------------------------------------------
  279. // TEDocument::DoActivate -    
  280. //
  281.     void TEDocument::DoActivate( Boolean becomingActive )
  282.     {
  283.         //change replace all this with a call to TXNFocus followed by a call to TXNActivate
  284.         TXNFocus( fMLTEObject, becomingActive );
  285.         TXNActivate( fMLTEObject, fMLTEFrameID, becomingActive);
  286.           
  287.     } /* TEDocument::DoActivate */
  288.  
  289.  
  290. //-----------------------------------------------------------------------
  291. // TEDocument::DoUpdate -    
  292. //
  293.     void TEDocument::DoUpdate(void)
  294.     {
  295.         //change: replace all this with a call to TXNUpdate.  TXNUpdate calls BeginUpdate/EndUpdate
  296.         //and handles drawing the scroll bars.
  297.         TXNUpdate ( fMLTEObject );
  298.         
  299.     } /* TEDocument::DoUpdate */
  300.  
  301.  
  302. //-----------------------------------------------------------------------
  303. // TEDocument::CalcIdle -    calculate how much idle time we need
  304. //
  305.     unsigned long TEDocument::CalcIdle(void)
  306.     {
  307.         //change: replace all this with a call to TXNGetSleepTicks
  308.         return TXNGetSleepTicks( fMLTEObject );
  309.         
  310.     } /* TEDocument::CalcIdle */
  311.  
  312.  
  313. //-----------------------------------------------------------------------
  314. // TEDocument::DoIdle -    This is called whenever we get a null event et al.
  315. //                         It takes care of necessary periodic actions. For
  316. //                         this program, it calls TEIdle.
  317. //
  318.     void TEDocument::DoIdle( void )
  319.     {
  320.         //change: replace TEIdle with a call to TXNIdle
  321.  
  322.         TXNIdle(fMLTEObject);
  323.  
  324.         
  325.     } /* TEDocument::DoIdle */
  326.  
  327.  
  328. //-----------------------------------------------------------------------
  329. // TEDocument::DrawWindow -    Draw the contents of an application window.
  330. //
  331. //change: completely remove the call the method DrawWindow
  332.  
  333.  
  334. //-----------------------------------------------------------------------
  335. // TEDocument::GetTERect -    Return a rectangle that is inset from the portRect
  336. //                             by the size of the scrollbars and a little extra margin.
  337. //
  338. //change: completely remove the method ::GetTERect
  339.  
  340.  
  341. //-----------------------------------------------------------------------
  342. // TEDocument::GetVisTERgn -    setup a region which contains the visible text
  343. //
  344. //change: completely remove the call the method GetVisTERgn
  345.  
  346.  
  347. //-----------------------------------------------------------------------
  348. // TEDocument::HaveSelection -    Return boolean value indicating that there is
  349. //                                 or is not a selection in the document
  350. //
  351. //change: completely remove the method HaveSelection
  352.     Boolean TEDocument::HaveSelection()
  353.     {
  354.         //replace guts with TXNIsSelectionEmpty
  355.         return !TXNIsSelectionEmpty( fMLTEObject );
  356.             
  357.     } /* TEDocument::HaveSelection */
  358.  
  359.  
  360. //-----------------------------------------------------------------------
  361. // TEDocument::AdjustViewRect -    Update the TERec's view rect so that it is the
  362. //                                 greatest multiple ofthe line Height that still
  363. //                                fits in the old viewRect.
  364. //
  365. //change: completely remove the method AdjustViewRect
  366.  
  367.  
  368. //-----------------------------------------------------------------------
  369. // TEDocument::AdjustTE -    Scroll the TERec around to match up to the potentially
  370. //                             updated scrollbar values. This is really useful when
  371. //                             the window has been resized such that the scrollbars
  372. //                            became inactive but the TERec was already scrolled.
  373. //
  374. //change: completely remove the method AdjustTE
  375.  
  376.  
  377. //-----------------------------------------------------------------------
  378. // TEDocument::AdjustScrollSizes -    Re-calculate the position and size of the
  379. //                                     viewRect and the scrollbars. kScrollTweek
  380. //                                    compensates for off-by-one requirements of
  381. //                                     the scrollbars to have borders coincide
  382. //                                    with the growbox.
  383. //
  384. //change: completely remove the method AdjustScrollSizes
  385.  
  386.  
  387. //-----------------------------------------------------------------------
  388. // TEDocument::AdjustScrollbars -    Turn off the controls by jamming a zero into
  389. //                                    their contrlVis fields (HideControl erases them
  390. //                                    and we don't want that). If the controls are to
  391. //                                    be resized as well, call the procedure to do that,
  392. //                                    then call the procedure to adjust the maximum and
  393. //                                    current values. Finally re-enable the controls by
  394. //                                    jamming a $FF in their contrlVis fields (ShowControl
  395. //                                    re-draws the control, which may not be necessary).
  396. //
  397. //change: completely remove the method AdjustScrollbars
  398.  
  399. // Calculate the new control maximum value and current value, whether it is the horizontal or
  400.  
  401. //-----------------------------------------------------------------------
  402. // TEDocument::AdjustHV -    Turn off the controls by jamming a zero into vertical
  403. //                            scrollbar. The vertical max is calculated by comparing
  404. //                            the number of lines to the vertical size of the viewRect.
  405. //                            The horizontal max is calculated by comparing the
  406. //                            maximum document width to the width of the viewRect.
  407. //                            The current values are set by comparing the offset
  408. //                            between the view and destination rects. If necessary,
  409. //                            redraw the control by calling ShowControl.
  410. //
  411. //change: completely remove the method AdjustHV
  412.  
  413. //-----------------------------------------------------------------------
  414. // TEDocument::AdjustScrollValues -    Simply call the common adjust routine for
  415. //                                    the vertical and horizontal scrollbars.
  416. //
  417. //change: completely remove the method AdjustScrollValues
  418.  
  419.  
  420. //-----------------------------------------------------------------------
  421. // TEDocument::GetClickLoop -    
  422. //
  423. //change: completely remove the method GetClickLoop
  424.  
  425.  
  426. //-----------------------------------------------------------------------
  427. // TEDocument::GetTEHandle -    
  428. //
  429. //change: make GetTEHandle into GetMLTEObject
  430.     TXNObject TEDocument::GetMLTEObject( void )
  431.     {
  432.         return fMLTEObject;
  433.         
  434.     } /* TEDocument::GetTEHandle */
  435.  
  436.  
  437. //-----------------------------------------------------------------------
  438. // TEDocument::DoCut -    
  439. //
  440.     void TEDocument::DoCut( void )
  441.     {
  442.     //change: replace the guts of this with TXNCut
  443.     //notice that TXNCut does return a status which we
  444.     //are ignoring here.
  445.         (void)TXNCut( fMLTEObject );
  446.         
  447.     } /* TEDocument::DoCut */
  448.  
  449.  
  450. //-----------------------------------------------------------------------
  451. // TEDocument::DoCopy -    
  452. //
  453.     void TEDocument::DoCopy( void )
  454.     {
  455.     //change: replace the guts of this with a call to TXNCopy
  456.     //again TXNCopy returns an OSStatus which we are ignoring
  457.         (void)TXNCopy( fMLTEObject );
  458.         
  459.     } /* TEDocument::DoCopy */
  460.  
  461.  
  462. //-----------------------------------------------------------------------
  463. // TEDocument::DoPaste -    
  464. //
  465.     void TEDocument::DoPaste( void )
  466.     {
  467.     //change: replace the guts with a call to TXNPaste
  468.     //once again ignoring the status
  469.         (void)TXNPaste ( fMLTEObject );
  470.         
  471.     } /* TEDocument::DoPaste */
  472.  
  473.  
  474. //-----------------------------------------------------------------------
  475. // TEDocument::DoClear -    
  476. //
  477.     void TEDocument::DoClear( void )
  478.     {
  479.     //change: replace the guts with a call to TXNClear
  480.     //ignore the status
  481.         TXNClear( fMLTEObject );
  482.         
  483.     } /* TEDocument::DoClear */
  484.  
  485.  
  486.  
  487. /***********************************************************************/
  488. //
  489. // Global declarations
  490. //            Routines used by this class, which don't belong to the class since we use
  491. //            them as toolbox filter routines, and you cannot pass class methods as ProcPtrs.
  492. //
  493. /***********************************************************************/
  494.  
  495.  
  496. //-----------------------------------------------------------------------
  497. // CommonAction -    Common algorithm for pinning the value of a control.
  498. //                    It returns the actual amount the value of the control
  499. //                    changed.
  500. //
  501. //change: completely remove function CommonAction
  502.  
  503.  
  504. //-----------------------------------------------------------------------
  505. // VActionProc -    Determines how much to change the value of the vertical
  506. //                     scrollbar by and how much to scroll the TE record.
  507. //
  508. //change: completely remove VActionProc
  509.  
  510.  
  511. //-----------------------------------------------------------------------
  512. // HActionProc -    Determines how much to change the value of the horizontal
  513. //                     scrollbar by and how much to scroll the TE record.
  514. //
  515. //change: completely remove HActionProc
  516.  
  517.  
  518. //-----------------------------------------------------------------------
  519. // PascalClickLoop -Gets called from our assembly language routine (on the
  520. //                  68K, C on the PowerPC), ASMCLICKLOOP,
  521. //                    which is in turn called by the TEClick toolbox routine.
  522. //                    Saves the windows clip region, sets it to the portRect,
  523. //                    adjusts the scrollbar values to match the TE scroll amount,
  524. //                    then restores the clip region.
  525. //
  526. //change: completely remove PascalClickLoop
  527.  
  528.  
  529. //-----------------------------------------------------------------------
  530. // GetOldClickLoop -Gets called from our assembly language routine (on the
  531. //                  68K, C on the PowerPC), ASMCLICKLOOP,
  532. //                    which is in turn called by the TEClick toolbox routine. It
  533. //                    returns the address of the default ClickLoop routine that was
  534. //                    put into the TERec by TEAutoView to ASMCLICKLOOP so that it
  535. //                    can call it.
  536. //
  537. //change: completely remove TEClickLoopUPP
  538.  
  539.  
  540. //-----------------------------------------------------------------------
  541. // AlertUser -    
  542. //
  543.     void AlertUser( short errResID, short errCode )
  544.     {
  545.         Str255 message;
  546.     
  547.         SetCursor( &qd.arrow );
  548.         GetIndString( message, errResID, errCode );
  549.         ParamText( message,(ConstStr255Param) "\p", (ConstStr255Param)"\p", (ConstStr255Param)"\p" );
  550.         (void) Alert( rUserAlert,  nil );
  551.         
  552.     } /* AlertUser */
  553.  
  554. //change: completely remove ASMCLICKLOOP
  555.